package com.xgy.vue_role_system.config.security.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xgy.vue_role_system.entity.Permission;
import com.xgy.vue_role_system.entity.User;
import com.xgy.vue_role_system.service.PermissionService;
import com.xgy.vue_role_system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户认证处理器类
 * 调用自定义的方法，根据用户名查询用户信息,包括权限等
 * 重写security的认证方法，根据自己数据库的信息进行查询判断
 *         UserDetailsServiceImpl 封装成 UserDetails对象
 *      => AbstractDetailsAuthenticationProvider 的 PasswordEncoder() 校验
 *      => Authentication对象 给 AuthenticationManager 判断并进行认证处理
 */
@Component
public class CustomerUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Autowired
    private PermissionService permissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.findUserByUsername(username);

        if(Objects.isNull(user)){
            throw new UsernameNotFoundException("用户名或者密码错误！");
        }

        //查询当前登录用户拥有的权限菜单列表
        List<Permission> permissionList = permissionService.findPermissionListByUserId(user.getId());
        //通过菜单列表获取对应的权限编码列表
        List<String> codeList = permissionList.stream()
                .filter(item -> item != null)
                .map(item -> item.getCode()).filter(item -> item != null)
                .collect(Collectors.toList());


        //将权限编码列表转换成数组
        String[] codeArr = codeList.toArray(new String[codeList.size()]);
        //调用权限工具类，将权限数组生成security规定的权限列表Collection<? extends GrantedAuthority> authorities;
        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList(codeArr);
        //将权限列表设置到当前UserDetails对象中
        user.setAuthorities(authorityList);
        //将用户有的权限菜单类别设置到当前UserDetails对象中
        user.setPermissionList(permissionList);

        //查询成功
        return user;
    }
}
